package org.wakeful.conn;

import java.io.FileNotFoundException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.wakeful.cfg.Configuration;

/**
 *
 * @author atila camurca
 */
public class Connection {

   private static java.sql.Connection instance;
   private static ConnectionProperties cp;

   private Connection() {
   }

   public static java.sql.Connection getInstance() throws SQLException, Exception {
      if (instance == null) {
         connect();
      }
      return instance;
   }

   public static void connect() throws Exception {
      try {
         ConnectionProperties connProp = getConnProperties();
         Class.forName(connProp.getDriverClass());
         connProp.setUrl(toUrl(connProp));
         instance = DriverManager.getConnection(connProp.getUrl(), connProp.getUser(), connProp.getPassword());
      } catch (SQLException e) {
         throw new SQLException(e);
      }
   }

   public static ConnectionProperties getConnProperties() {
      if (cp == null) {
         Configuration config = new Configuration();
         try {
            cp = config.getConnectionProperties();
         } catch (FileNotFoundException ex) {
            ex.printStackTrace();
         } catch (Exception ex) {
            ex.printStackTrace();
         }
      }
      return cp;
   }

   /**
    * Works for PostgreSQL only, for a while ... :)
    * @throws SQLException
    * @throws Exception
    */
   public static void testConnection() throws Exception {
      String sql = "SELECT version()";
      Statement stmt = getInstance().createStatement();
      ResultSet rs = stmt.executeQuery(sql);
      if (rs.next()) {
         System.out.println("Version: " + rs.getString("version"));
      }
      stmt.close();
      rs.close();
   }

   public static java.sql.Connection testConnectionParameters(ConnectionProperties cp) throws Exception {
      java.sql.Connection conn = null;
      try {
         if (cp.getUrl() == null) {
            cp.setUrl(toUrl(cp));
         }
         conn = DriverManager.getConnection(cp.getUrl(), cp.getUser(), cp.getPassword());
      } catch (Exception e) {
         throw new Exception(e);
      }
      return conn;
   }

   public static void closeTestConnection(java.sql.Connection conn) throws Exception {
      conn.close();
   }

   public static String getSchema() {
      return getConnProperties().getSchema();
   }

   private static String toUrl(ConnectionProperties cp) {
      StringBuilder sqlquery = new StringBuilder();
      if ("postgresql".equals(cp.getDialect())) {
         sqlquery.append("jdbc:").append(cp.getDialect()).append("://").append(cp.getHost()).append(":").append(cp.getPort()).append("/").append(cp.getDbName());
         cp.setUrl(sqlquery.toString());
      } else if ("firebirdsql".equals(cp.getDialect())) {
         sqlquery.append("jdbc:").append(cp.getDialect()).append(":").append(cp.getHost()).append("/").append(cp.getPort()).append(":").append(cp.getDbName());
         cp.setUrl(sqlquery.toString());
      }
      return cp.getUrl();
   }

   public static void reset() {
      instance = null;
      cp = null;
   }

   public static void closeConnection() throws Exception {
      try {
         if (!instance.isClosed()) {
            instance.close();
         }
         reset();
      } catch (Exception e) {
         throw new Exception(e);
      }
   }
}
